﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using SMBL.Interface.LifeCycle;
using SMBL.Interface.Document;

namespace SMBL.AFS.Providers
{
    /// <summary>
    /// The document provider
    /// Provide the basic operation of the document.
    /// When a file is be opened as an xml file, other operations
    /// such as write and save will no longer work.
    /// This provider is based on a file information.
    /// @Author: Push
    /// </summary>
    public class Document : IDocProvider
    {
        /// <summary>
        /// @Parameter: FormatedFilePath
        /// This parameter store the file path. Used by the file information
        /// @Author: Push
        /// </summary>
        private String myFormatedFilePath;
        // Real Only
        public String FormatedFilePath
        {
            get { return myFormatedFilePath; }
        }

        /// <summary>
        /// My File Information Class
        /// </summary>
        private FileInfo myFile;
        private StreamReader myReader = null;
        /// <summary>
        /// The String buffer.
        /// </summary>
        private String myBuffer;
        private Boolean beAppended = false;
        private Boolean beXml = false;

        /// <summary>
        /// The Construction of this Provider.
        /// Should send in a formated file path to initialize it.
        /// @Author: Push
        /// </summary>
        /// <param name="FormatedFilePath"></param>
        public Document(String FormatedFilePath)
        {
            myFormatedFilePath = FormatedFilePath;
        }

        #region IStart Members

        /// <summary>
        /// Start the provider
        /// Initialize the file information and the string buffer.
        /// @Author: Push
        /// </summary>
        /// <returns></returns>
        public bool Start()
        {
            myFile = new FileInfo(Global.WebSite.AppPath + myFormatedFilePath);
            //beExisted = myFile.Exists;
            myBuffer = "";
            return true;
        }

        #endregion

        #region IEnd Members

        /// <summary>
        /// End the provider
        /// Release the resource
        /// @Author: Push
        /// </summary>
        /// <returns></returns>
        public bool End()
        {
            myFile = null;
            myBuffer = null;
            myReader.Close();
            return true;
        }

        #endregion

        #region IDocProcessor Members

        /// <summary>
        /// Delete the file
        /// Then end the provider
        /// @Author: Push
        /// </summary>
        public void Delete()
        {
            myFile.Delete();
            this.End();
        }

        #endregion

        #region IDocBasic Members

        /// <summary>
        /// Save the buffer to the file.
        /// If the file has been used as an XML file, directly return.
        /// @Author: Push
        /// </summary>
        public void Save()
        {
            // Check if is XML file
            if (beXml) return;
            FileStream tmpStream = null;
            // Check write mode
            if (beAppended)
            {
                tmpStream = myFile.Open(FileMode.Append);
            }
            else
            {
                tmpStream = myFile.Open(FileMode.Truncate);
            }
            StreamWriter tmpWriter = new StreamWriter(tmpStream);
            tmpWriter.Write(myBuffer);
            // Release resource
            tmpWriter.Close();
            tmpStream.Close();
        }

        /// <summary>
        /// Create a new file
        /// Will throw exception when the file existed.
        /// @Author: Push
        /// </summary>
        public void New()
        {
            FileStream tmpStream = myFile.Open(FileMode.CreateNew);
            tmpStream.Close();
        }

        /// <summary>
        /// Open the file as an XML document
        /// return null if the file does not existe
        /// @Author: Push
        /// </summary>
        /// <returns></returns>
        public System.Xml.XmlDocument OpenAsXML()
        {
            if (!myFile.Exists) return null;
            System.Xml.XmlDocument rtnXml = new System.Xml.XmlDocument();
            rtnXml.Load(myFile.FullName);

            this.beXml = true;
            return rtnXml;
        }

        #endregion

        #region IDocEdit Members

        /// <summary>
        /// Append the content to the buffer.
        /// Set the buffer mode(Write or Append)
        /// @Author: Push
        /// </summary>
        /// <param name="Content"></param>
        public void Write(string Content)
        {
            if (beXml) return;
            if (beAppended)
            {
                myBuffer = "";
                beAppended = false;
            }
            myBuffer += Content;
        }

        /// <summary>
        /// Append the content to the buffer.
        /// Set the buffer mode to Append
        /// @Author: Push
        /// </summary>
        /// <param name="Content"></param>
        public void Append(string Content)
        {
            if (beXml) return;
            if (!beAppended)
            {
                myBuffer = "";
                beAppended = true;
            }
            myBuffer += Content;
        }

        /// <summary>
        /// Read one line from the file
        /// Re-open the file if reach the end of the file.
        /// @Author: Push
        /// </summary>
        /// <returns></returns>
        public string ReadLine()
        {
            if (!myFile.Exists)
            {
                return null;
            }
            if (myReader == null)
            {
                myReader = new StreamReader(myFile.OpenRead());
            }
            String tmpRtn = myReader.ReadLine();
            // Reach the end of the file
            if (tmpRtn == null)
            {
                // Reset the reader
                myReader.Close();
                myReader = null;
            }
            return tmpRtn;
        }

        /// <summary>
        /// Read to the end of the file from current position.
        /// Re-open the file after reading.
        /// @Author: Push
        /// </summary>
        /// <returns></returns>
        public string RealToEnd()
        {
            if (!myFile.Exists)
            {
                return null;
            }
            if (myReader == null)
            {
                myReader = new StreamReader(myFile.OpenRead());
            }
            String tmpRtn = myReader.ReadToEnd();
            // Reset the reader
            myReader.Close();
            myReader = null;

            return tmpRtn;
        }

        #endregion

        #region IAProvider Members

        public bool Lock()
        {
            throw new NotImplementedException();
        }

        public bool Lock(int TimeOut)
        {
            throw new NotImplementedException();
        }

        public void UnLock()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
